package manager;

import facade.RoleFacade;
import facade.UserFacade;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import remoteEntity.User;

/**
 * UserManager
 *
 * Handle User operations and keeps user state.
 */
//TODO: implemnt the remote interface
/**
 * TODO: This bean works poorly when connecting through the remote interface, since 
 * entities passed from it become detatched, and thus clienside changes to the entity
 * are not retained. The entity must be sent back to the server and cosilidated into the DB
 * for this to work. Therefore, its best to implement methods for setting entity properties 
 * directly in this class, and never passing the entities to the client.
 */
@Stateful
@LocalBean
public class UserManager implements UserManagerRemote{

    @EJB
    private RoleFacade roleFacade;
    @EJB
    private UserFacade userFacade;
    private User user;
    private boolean loggedIn;
    private boolean initialized = false;

    @PostConstruct
    private void init() {
        System.out.println("init usermanager: "+this);
        this.user = getGuestUser();
        initialized = true;
    }
    

    @Override
    public boolean getLoggedIn() {
        return loggedIn;
    }

    /**
     * not exposed in remote interface for securit reasons.
     * @param loggedIn 
     */
    public void setLoggedIn(boolean loggedIn) {
        System.out.println(this+"setting logged in");
        this.loggedIn = loggedIn;
    }
    
    /**
     * User must be manually set first! Can not be used to get the current user.
     * 
     * If you intend to change values in the user entity class returned, remember to
     * set it afterwards! (local changes will not be stored until then)
     * 
     * @return 
     */
    @Override
    public User getUser() {
        return user;
    }

    /**
     * not exposed in remote interface for securit reasons.
     * @param user 
     */
    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public User getGuestUser() {
        User _user = new User();
        _user.setRole(roleFacade.getGuestRole());
        return _user;
    }

    @Override
    public void register() throws Exception {
        userFacade.register(user);
        this.loggedIn = true;
    }

    @Override
    public User login() throws Exception {
        System.out.println(this+"manager attempting login for "+user.getUsername());
        this.user = userFacade.login(user);
        if (this.user == null){
            this.user = getGuestUser();
            throw new Exception("Could not log in!");
            //
            //return user;
        } else {
            this.loggedIn = true;
            return user;
        }
    }

    @Override
    public boolean getIsAdmin() {
        return roleFacade.getAdminRole().
                getId().equals(user.getRole().
                getId());
    }

    @Override
    public User getUserById(int id) {
        return userFacade.find(id);
    }

    @Override
    public boolean getIsAdmin(int id) {
        User foundUser = getUserById(id);
        if (foundUser == null) {
            return false;
        }
        return roleFacade.getAdminRole().
                getId().equals(foundUser.getRole().
                getId());
    }

    @Override
    public void promote(int id) {
        User foundUser = getUserById(id);
        if (foundUser == null) {
            return;
        }
        userFacade.setRole(foundUser, roleFacade.getAdminRole());
    }

    @Override
    public void demote(int id) {
        User foundUser = getUserById(id);
        if (foundUser == null) {
            return;
        }
        userFacade.setRole(foundUser, roleFacade.getUserRole());
    }

    /**
     * Sets all the fields of the user entity for this manager.
     * If a parameter is null, it will be ignored (i.e setting just username and all
     * other parameters to null will resut in only username beeing set.
     * @param username
     * @param password
     * @param email
     * @param firstname
     * @param lastname 
     */
    @Override
    public void setFields(String username, String password, String email, String firstname, String lastname) {
        if (username != null)
            this.user.setUsername(username);
        if (username != null)
            this.user.setEmail(email);
        if (username != null)
            this.user.setFirstname(firstname);
        if (username != null)
            this.user.setLastname(lastname);
        if (username != null)
            this.user.setPassword(password);
    }
}
